home *** CD-ROM | disk | FTP | other *** search
/ SPACE 1 / SPACE - Library 1 - Volume 1.iso / misc~1 / 5 / osspascl / aesvdi.doc next >
Text File  |  1985-11-19  |  12KB  |  272 lines

  1. MAKING GENERIC AES AND VDI CALLS FROM PERSONAL PASCAL
  2. -----------------------------------------------------
  3.  
  4. As some of you have discovered, because of prior experience with the Atari ST
  5. developer's package, there are a number of calls within the GEM system (AES and
  6. VDI) which are not yet supported by Personal Pascal.  Luckily, within the
  7. PASGEM library there are two routines which already support additional calls to
  8. GEM.  This document gives you the information you need in order to call these
  9. two generic GEM routines.
  10.  
  11. AES CALLS
  12. ---------
  13.  
  14. First of all, we are going to tackle AES calls.  In the process of explaining
  15. how to call the generalized AES routine, we will be implementing a new call
  16. which is not supported by Pascal.  This routine, which is called "graf_mkstate"
  17. in the C bindings, returns the current state of the mouse buttons and the key-
  18. board modifier keys (i.e., alternate, left and right shift keys, and control).
  19. This routine takes four parameters which are the addresses of four two-byte
  20. variables in which to put the mouse and keyboard state information.  Since
  21. passing an address in Pascal is equivalent to passing a variable as a VAR
  22. parameter, the declaration of the routine we're going to construct is going
  23. to start like this:
  24.  
  25.   (* Mouse_Key_State - Return the current mouse position and the state of both
  26.       the mouse buttons and the keyboard modifier keys. *)
  27.  
  28.   PROCEDURE Mouse_Key_State( VAR x, y, buttons, keys : integer ) ;
  29.  
  30. Before we start filling in the rest of the procedure, we have to look at how
  31. parameters are passed to the AES.  There are four separate areas in which
  32. values are passed to and returned from AES.  The first area is the "global
  33. parameter area", where AES stores various parameters it needs to keep around
  34. between calls.  Since the application program should not modify these values,
  35. there is no way to access the "global" array from Pascal.  The second area is
  36. the "integer input array", in which various integer values may be passed to
  37. AES.  Similarly, there is an "integer output array" in which AES passes values
  38. back to the calling program.  The fourth and fifth arrays are the "address
  39. input array" and the "address output array".  These two areas will contain
  40. address parameters passed to or from AES.  The Pascal library keeps track of
  41. the global parameter area, since it must remain intact, but the other arrays
  42. must be declared in your GEM program if you want to make calls to the AES
  43. handler.  In order to declare the arrays easily, we will set up their types
  44. first:
  45.  
  46.   TYPE
  47.     Pointer = ^char ;   (* Just a filler declaration! *)
  48.     Int_In_Parms    = ARRAY [ 0..15 ] OF integer ;
  49.     Int_Out_Parms   = ARRAY [ 0..45 ] OF integer ;
  50.     Addr_In_Parms   = ARRAY [ 0..1 ] OF Pointer ;
  51.     Addr_Out_Parms  = ARRAY [ 0..0 ] OF Pointer ;
  52.  
  53. The declaration of "Pointer" is just used to emphasize that the address in and
  54. out parameters are ADDRESSES, and not just numeric values.  Notice that the
  55. integer arrays only have lengths 16 and 46, respectively.  This is sufficient
  56. for most calls, but if you want to make a call to VDI (see below) which needs
  57. more slots in these arrays, increase the size accordingly.  Now that we know
  58. the TYPEs of the local variables we need, we can declare them:
  59.  
  60.   VAR
  61.     int_in   : Int_In_Parms ;
  62.     int_out  : Int_Out_Parms ;
  63.     addr_in  : Addr_In_Parms ;
  64.     addr_out : Addr_Out_Parms ;
  65.  
  66. OK, we're ready to look into the actual routine which we will be calling to
  67. interface to GEM.  It takes five parameters.  The first is the AES call number,
  68. which is 79 for out "graf_mkstate" call.  The next four parameters are just the
  69. arrays which we just declared, passed as VAR parameters.  The routine should be
  70. declared EXTERNAL as follows:
  71.  
  72.   PROCEDURE AES_Call( op : integer ;
  73.                 VAR int_in : Int_In_Parms ; VAR int_out : Int_Out_Parms ;
  74.                 VAR addr_in : Addr_In_Parms ; VAR addr_out : Addr_Out_Parms ) ;
  75.     EXTERNAL ;
  76.  
  77. Now that we know all of our variables and parameters, and everything the
  78. AES_Call routine is expecting, we can look at what we need to do to actually
  79. perform the GEM call.  According to the AES documentation, the "graf_mkstate"
  80. call doesn't expect any parameters, and it returns the results in the "integer
  81. output array" as follows:
  82.  
  83.     int_out[0] -- error code (0 if no error occurred)
  84.     int_out[1] -- current mouse x position
  85.     int_out[2] -- mouse y position
  86.     int_out[3] -- mouse button state
  87.     int_out[4] -- keyboard modifier state
  88.  
  89. We should never get an error with this call, since no parameters are passed in,
  90. so we're going to ignore the error code.  This isn't a good idea in general,
  91. but it simplifies our presentation somewhat.  The complete code required to
  92. perform the call and return the result values in the proper parameters is as
  93. follows:
  94.  
  95.   BEGIN
  96.     AES_Call( 79, int_in, int_out, addr_in, addr_out ) ;
  97.     x := int_out[1] ;
  98.     y := int_out[2] ;
  99.     buttons := int_out[3] ;
  100.     keys    := int_out[4] ;
  101.   END ;
  102.  
  103. To summarize this section on making AES calls, here is a complete listing of
  104. the Mouse_Key_State routine, without the intervening text:
  105.  
  106.   (* Mouse_Key_State - Return the current mouse position and the state of both
  107.       the mouse buttons and the keyboard modifier keys. *)
  108.  
  109.   PROCEDURE Mouse_Key_State( VAR x, y, buttons, keys : integer ) ;
  110.  
  111.     TYPE
  112.       Pointer = ^char ;   (* Just a filler declaration! *)
  113.       Int_In_Parms    = ARRAY [ 0..15 ] OF integer ;
  114.       Int_Out_Parms   = ARRAY [ 0..45 ] OF integer ;
  115.       Addr_In_Parms   = ARRAY [ 0..1 ] OF Pointer ;
  116.       Addr_Out_Parms  = ARRAY [ 0..0 ] OF Pointer ;
  117.  
  118.     VAR
  119.       int_in   : Int_In_Parms ;
  120.       int_out  : Int_Out_Parms ;
  121.       addr_in  : Addr_In_Parms ;
  122.       addr_out : Addr_Out_Parms ;
  123.  
  124.     PROCEDURE AES_Call( op : integer ;
  125.                 VAR int_in : Int_In_Parms ; VAR int_out : Int_Out_Parms ;
  126.                 VAR addr_in : Addr_In_Parms ; VAR addr_out : Addr_Out_Parms ) ;
  127.       EXTERNAL ;
  128.  
  129.     BEGIN
  130.       AES_Call( 79, int_in, int_out, addr_in, addr_out ) ;
  131.       x := int_out[1] ;
  132.       y := int_out[2] ;
  133.       buttons := int_out[3] ;
  134.       keys    := int_out[4] ;
  135.     END ;
  136.  
  137. VDI CALLS
  138. ---------
  139.  
  140. Accessing the VDI system is very similar to the discussion of AES calls above.
  141. The only main difference is that, although there is a "global parameter array",
  142. it doesn't need to stay intact.  Also, sometimes you need to get return values
  143. in this array.  Also, no address parameters are ever passed, but a new type of
  144. value is passed and returned, points.  So the TYPE declarations for the various
  145. arrays we need are slightly different:
  146.  
  147.   TYPE
  148.     Ctrl_Parms      = ARRAY [ 0..11 ] OF integer ;
  149.     Int_In_Parms    = ARRAY [ 0..15 ] OF integer ;
  150.     Int_Out_Parms   = ARRAY [ 0..45 ] OF integer ;
  151.     Pts_In_Parms    = ARRAY [ 0..11 ] OF integer ;
  152.     Pts_Out_Parms   = ARRAY [ 0..11 ] OF integer ;
  153.  
  154. For our VDI calling example, we're going to implement the call which allows you
  155. to control the height of text that is drawn using the "Draw_String" call.  This
  156. call is known in the VDI documentation as "vst_height", but we're going to
  157. declare it like this:
  158.  
  159.   (* Text_Height - Set the height in pixels of text, when it is drawn using the
  160.       Draw_String library call. *)
  161.  
  162.   PROCEDURE Text_Height( height : integer ) ;
  163.  
  164. Again, we need to declare the variables which we are going to pass to VDI:
  165.  
  166.     VAR
  167.       control : Ctrl_Parms ;
  168.       int_in  : Int_In_Parms ;
  169.       int_out : Int_Out_Parms ;
  170.       pts_in  : Pts_In_Parms ;
  171.       pts_out : Pts_Out_Parms ;
  172.  
  173. The actual generic routine we are going to call to perform VDI operations is
  174. very similar to the AES_Call routine described above.  One difference is that
  175. we pass two command numbers instead of one.  The second number is only used
  176. when we call the GSX graphics primitives; it is the GSX primitive number which
  177. we want to use.  For all non-GSX calls (i.e., most of the time), this second
  178. number will be zero (as it is in this case).  Also, there is one additional
  179. parameter, called "translate" in the declaration below, which specifies whether
  180. to translate the points in the "pts_in" and "pts_out" array RELATIVE to the
  181. current origin.  What this means is that if you use the Set_Window call to
  182. make a window current, all points passed to or from VDI will be translated
  183. to screen coordinates such that (0,0) is equivalent to the upper left of that
  184. window, PROVIDED the value of "translate" is true.  If you don't want such
  185. translation to occur (we don't, in this case, since the "point" we are passing
  186. is actually the height we want!), pass in "false" for this parameter.  The
  187. declaration of the generic VDI call is as follows:
  188.  
  189.   PROCEDURE VDI_Call( cmd, sub_cmd : integer ; nints, npts : integer ;
  190.                 VAR ctrl : Ctrl_Parms ;
  191.                 VAR int_in : Int_In_Parms ; VAR int_out : Int_Out_Parms ;
  192.                 VAR pts_in : Pts_In_Parms ; VAR pts_out : Pts_Out_Parms ;
  193.                 translate : boolean ) ;
  194.     EXTERNAL ;
  195.  
  196. Notice that we must tell VDI the number of integers and points which we are
  197. passing.  The particular call we want to use is number 12, "set character
  198. height, absolute mode".  It expects two parameters, as follows:
  199.  
  200.     pts_in[0] -- 0 (the value zero)
  201.     pts_in[1] -- desired height in pixels
  202.  
  203. It returns several parameters:
  204.  
  205.     pts_out[0] -- character width selected
  206.     pts_out[1] -- character height selected
  207.     pts_out[2] -- character cell width selected
  208.     pts_out[3] -- character cell height selected
  209.  
  210. Why are there four return values instead of two?  The first two (0 and 1) are
  211. usually SMALLER than the other two, for the following reason.  The "character
  212. height" (not cell height) is measured from the baseline (the bottom of capital
  213. letters) to the top line (the top of capitals, including a little space).  The
  214. character width is, similarly, measured from the left edge to the right edge
  215. of characters.  The "cell width" and "cell height", on the other hand, are
  216. measured from the very bottom to the very top and the very left to the very
  217. right of the "cell" in which a character is drawn.  Since some space is put
  218. on all sides of a character, the "cell" measurements are a little larger than
  219. the other measurements.  We're actually going to ignore all of the return
  220. parameters, since we just want to set the values and assume they are correct.
  221. The main body of our PROCEDURE is, then:
  222.  
  223.   BEGIN
  224.     pts_in[0] := 0 ;
  225.     pts_in[1] := height ;
  226.     VDI_Call( 12, 0, 0, 2, control, int_in, int_out, pts_in, pts_out, false ) ;
  227.   END ;
  228.  
  229. In order to look at the routine as a whole, here are all the neccessary
  230. declarations and code together, without the intervening text:
  231.  
  232.   (* Text_Height - Set the height in pixels of text, when it is drawn using the
  233.       Draw_String library call. *)
  234.  
  235.   PROCEDURE Text_Height( height : integer ) ;
  236.  
  237.     TYPE
  238.       Ctrl_Parms      = ARRAY [ 0..11 ] OF integer ;
  239.       Int_In_Parms    = ARRAY [ 0..15 ] OF integer ;
  240.       Int_Out_Parms   = ARRAY [ 0..45 ] OF integer ;
  241.       Pts_In_Parms    = ARRAY [ 0..11 ] OF integer ;
  242.       Pts_Out_Parms   = ARRAY [ 0..11 ] OF integer ;
  243.  
  244.     VAR
  245.       control : Ctrl_Parms ;
  246.       int_in  : Int_In_Parms ;
  247.       int_out : Int_Out_Parms ;
  248.       pts_in  : Pts_In_Parms ;
  249.       pts_out : Pts_Out_Parms ;
  250.  
  251.     PROCEDURE VDI_Call( cmd, sub_cmd : integer ; nints, npts : integer ;
  252.                 VAR ctrl : Ctrl_Parms ;
  253.                 VAR int_in : Int_In_Parms ; VAR int_out : Int_Out_Parms ;
  254.                 VAR pts_in : Pts_In_Parms ; VAR pts_out : Pts_Out_Parms ;
  255.                 translate : boolean ) ;
  256.       EXTERNAL ;
  257.  
  258.     BEGIN
  259.       pts_in[0] := 0 ;
  260.       pts_in[1] := height ;
  261.       VDI_Call(12, 0, 0, 2, control, int_in, int_out, pts_in, pts_out, false);
  262.     END ;
  263.  
  264.  
  265. Press <CR> to continue: 
  266.  
  267. [72477,3703]
  268. AESVDI.DOC                06-Mar-86(07-Mar-86) 11995
  269.     12
  270.  
  271.  
  272. (R D T):